Skip to content

Reject secret scope permissions with no principal - #6215

Merged
radakam merged 3 commits into
mainfrom
fix-secret-scope-permission-principal
Aug 17, 2026
Merged

Reject secret scope permissions with no principal#6215
radakam merged 3 commits into
mainfrom
fix-secret-scope-permission-principal

Conversation

@radakam

@radakam radakam commented Aug 10, 2026

Copy link
Copy Markdown
Contributor

Changes

Add errorForInvalidSecretScopePermissions to validate.Required(). Validate and deploy fail early with:

Error: secret scope permission principal is required
  at resources.secret_scopes.<key>.permissions[0]

Set one of user_name, group_name or service_principal_name

Diagnostics point at the scope (ApplyBundlePermissions drops per-entry locations). sortDiagnostics ties on path when locations match.

Why

A secret scope permission with no principal passes bundle validate (only a type warning for wrong-typed values). Three shapes slip through: missing, empty-string, and wrong-typed principal (normalization warns and drops it).

Without this check, failure is late and engine-specific:

Direct — deploy fails in SecretScopeFixups before any //secrets calls:

Error: Failed to collapse permissions for secret scope
  at resources.secret_scopes.no_principal

missing principal in permissions for secret scope "test-scope-no-principal"

Terraform — deploy succeeds and creates scopes plus ACLs with "principal": "". Destroy then fails and cannot clean up:

Error: cannot read secret acl: principal cannot be empty

  with databricks_secret_acl.secret_acl_no_principal_0,
  on bundle.tf.json line 30, in resource.databricks_secret_acl.secret_acl_no_principal_0:
  30:       },

Found by fuzz testing.

Tests

New acceptance test bundle/validate/secret_scope_required_principal covering the three bad shapes plus a valid one. Asserts early rejection and zero //secrets requests on deploy.

A secret scope permission that names no principal is accepted by
`bundle validate` today, but the backend rejects a secret ACL with an
empty principal. The direct engine only fails later while collapsing
permissions, and Terraform creates the scope before the ACL call fails,
leaving a partial deploy that `destroy` cannot clean up.

Reject the input at validation time so both engines fail early with a
located, actionable error. A principal of the wrong type counts as
missing: normalization only warns and drops the value, so the permission
would otherwise still reach the backend without a principal.
@eng-dev-ecosystem-bot

eng-dev-ecosystem-bot commented Aug 10, 2026

Copy link
Copy Markdown
Collaborator

Integration test report

Commit: 65171ea

Run: 31486274522

Env 🔄​flaky 💚​RECOVERED 🙈​SKIP ✅​pass 🙈​skip Time
💚​ aws linux 4 4 294 1129 6:33
💚​ aws windows 4 4 296 1127 6:48
🔄​ azure linux 4 4 4 289 1129 7:12
💚​ azure windows 4 4 295 1127 6:36
🔄​ gcp linux 1 1 5 293 1129 8:30
💚​ gcp windows 1 5 296 1127 6:44
13 interesting tests: 5 flaky, 4 RECOVERED, 4 SKIP
Test Name aws linux aws windows azure linux azure windows gcp linux gcp windows
💚​ TestAccept 💚​R 💚​R 💚​R 💚​R 💚​R 💚​R
🙈​ TestAccept/bundle/invariant/no_drift 🙈​S 🙈​S 🙈​S 🙈​S 🙈​S 🙈​S
🙈​ TestAccept/bundle/resources/vector_search_endpoints/drift/recreated_same_name 🙈​S 🙈​S 🙈​S 🙈​S 🙈​S 🙈​S
🙈​ TestAccept/bundle/resources/vector_search_indexes/recreate/embedding_dimension 🙈​S 🙈​S 🙈​S 🙈​S 🙈​S 🙈​S
🙈​ TestAccept/ssh/connection 🙈​S 🙈​S 🙈​S 🙈​S 🙈​S 🙈​S
🔄​ TestFsCpFileToFileFileNotOverwritten ✅​p ✅​p 🔄​f ✅​p ✅​p ✅​p
🔄​ TestFsCpFileToFileFileNotOverwritten/uc-volumes_to_uc-volumes ✅​p ✅​p 🔄​f ✅​p ✅​p ✅​p
🔄​ TestSyncNestedFolderSync ✅​p ✅​p ✅​p ✅​p 🔄​f ✅​p
🔄​ TestFilerWorkspaceNotebook ✅​p ✅​p 🔄​f ✅​p ✅​p ✅​p
🔄​ TestFilerWorkspaceNotebook/scalaJupyterNb.ipynb ✅​p ✅​p 🔄​f ✅​p ✅​p ✅​p
💚​ TestFetchRepositoryInfoAPI_FromRepo 💚​R 💚​R 💚​R 💚​R 🙈​S 🙈​S
💚​ TestFetchRepositoryInfoAPI_FromRepo/root 💚​R 💚​R 💚​R 💚​R
💚​ TestFetchRepositoryInfoAPI_FromRepo/subdir 💚​R 💚​R 💚​R 💚​R
Top 6 slowest tests (at least 2 minutes):
duration env testname
6:40 aws windows TestAccept
6:36 gcp windows TestAccept
6:27 azure windows TestAccept
3:03 azure linux TestAccept
3:02 gcp linux TestAccept
3:01 aws linux TestAccept

@radakam
radakam marked this pull request as ready for review August 11, 2026 08:18
Drop dyn.MapByPattern in favor of iterating SecretScopes, and keep
comments to the non-obvious bits (wrong-typed drop, without-fix behavior).

@denik denik left a comment

Copy link
Copy Markdown
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Thanks!

@radakam
radakam added this pull request to the merge queue Aug 17, 2026
Merged via the queue into main with commit 1cfa6b6 Aug 17, 2026
26 checks passed
@radakam
radakam deleted the fix-secret-scope-permission-principal branch August 17, 2026 11:23
@eng-dev-ecosystem-bot

Copy link
Copy Markdown
Collaborator

Integration test report

Commit: 1cfa6b6

Run: 32024816334

Env ❌​FAIL 🟨​KNOWN 🔄​flaky 💚​RECOVERED 🙈​SKIP ✅​pass 🙈​skip Time
❌​ aws linux 15 4 2 2 1161 954 203:19
❌​ aws windows 9 4 4 2 2 1102 973 249:43
❌​ azure linux 9 4 2 2 2 1059 991 207:15
❌​ azure windows 9 1 1 5 2 999 1010 233:40
❌​ gcp linux 9 1 8 2 3 1043 995 224:50
❌​ gcp windows 9 1 2 2 3 988 1014 236:46
38 interesting tests: 15 flaky, 15 FAIL, 4 KNOWN, 2 RECOVERED, 2 SKIP
Test Name aws linux aws windows azure linux azure windows gcp linux gcp windows
🟨​ TestAccept 🟨​K 🟨​K 🟨​K 🟨​K 🟨​K 🟨​K
💚​ TestAccept/bundle/invariant/no_drift 💚​R 💚​R 💚​R 💚​R 💚​R 💚​R
🔄​ TestAccept/bundle/resources/dashboards/change-name ✅​p ✅​p ✅​p ✅​p 🔄​f 🔄​f
🔄​ TestAccept/bundle/resources/dashboards/change-name/DATABRICKS_BUNDLE_ENGINE=terraform ✅​p ✅​p ✅​p ✅​p 🔄​f 🔄​f
❌​ TestAccept/bundle/resources/dashboards/dataset-catalog-schema ❌​F ❌​F ❌​F ❌​F ❌​F ❌​F
❌​ TestAccept/bundle/resources/dashboards/dataset-catalog-schema/DATABRICKS_BUNDLE_ENGINE=direct ❌​F ❌​F ❌​F ❌​F ❌​F ❌​F
❌​ TestAccept/bundle/resources/dashboards/dataset-catalog-schema/DATABRICKS_BUNDLE_ENGINE=terraform ❌​F ❌​F ❌​F ❌​F ❌​F ❌​F
❌​ TestAccept/bundle/resources/dashboards/delete-trashed-out-of-band ❌​F ❌​F ❌​F ❌​F ❌​F ❌​F
❌​ TestAccept/bundle/resources/dashboards/delete-trashed-out-of-band/DATABRICKS_BUNDLE_ENGINE=direct ❌​F ❌​F ❌​F ❌​F ❌​F ❌​F
❌​ TestAccept/bundle/resources/dashboards/delete-trashed-out-of-band/DATABRICKS_BUNDLE_ENGINE=terraform ❌​F ❌​F ❌​F ❌​F ❌​F ❌​F
❌​ TestAccept/bundle/resources/dashboards/simple ❌​F ❌​F ❌​F ❌​F ❌​F ❌​F
❌​ TestAccept/bundle/resources/dashboards/simple/DATABRICKS_BUNDLE_ENGINE=direct ❌​F ❌​F ❌​F ❌​F ❌​F ❌​F
❌​ TestAccept/bundle/resources/dashboards/simple/DATABRICKS_BUNDLE_ENGINE=terraform ❌​F ❌​F ❌​F ❌​F ❌​F ❌​F
🔄​ TestAccept/bundle/resources/dashboards/simple_syncroot ✅​p 🔄​f ✅​p ✅​p ✅​p ✅​p
🔄​ TestAccept/bundle/resources/dashboards/simple_syncroot/DATABRICKS_BUNDLE_ENGINE=direct ✅​p 🔄​f ✅​p ✅​p ✅​p ✅​p
🔄​ TestAccept/bundle/resources/grants/schemas/remove_all ✅​p ✅​p ✅​p ✅​p 🔄​f ✅​p
🔄​ TestAccept/bundle/resources/grants/schemas/remove_all/DATABRICKS_BUNDLE_ENGINE=direct ✅​p ✅​p ✅​p ✅​p 🔄​f ✅​p
🔄​ TestAccept/bundle/resources/grants/schemas/remove_principal ✅​p ✅​p ✅​p ✅​p 🔄​f ✅​p
🔄​ TestAccept/bundle/resources/grants/schemas/remove_principal/DATABRICKS_BUNDLE_ENGINE=terraform ✅​p ✅​p ✅​p ✅​p 🔄​f ✅​p
❌​ TestAccept/bundle/resources/permissions/dashboards/create ❌​F ✅​p ✅​p ✅​p 🙈​s 🙈​s
❌​ TestAccept/bundle/resources/permissions/dashboards/create/DATABRICKS_BUNDLE_ENGINE=terraform ❌​F ✅​p ✅​p ✅​p
❌​ TestAccept/bundle/resources/permissions/jobs/delete_one ❌​F ✅​p ✅​p ✅​p ✅​p ✅​p
❌​ TestAccept/bundle/resources/permissions/jobs/delete_one/DATABRICKS_BUNDLE_ENGINE=direct ❌​F ✅​p ✅​p ✅​p ✅​p ✅​p
🔄​ TestAccept/bundle/resources/postgres_branches/recreate ✅​p 🔄​f 🙈​s 🙈​s 🙈​s 🙈​s
🔄​ TestAccept/bundle/resources/postgres_branches/recreate/DATABRICKS_BUNDLE_ENGINE=terraform ✅​p 🔄​f
🔄​ TestAccept/bundle/resources/quality_monitors/change_output_schema_name ✅​p ✅​p ✅​p ✅​p 🔄​f ✅​p
🔄​ TestAccept/bundle/resources/quality_monitors/change_output_schema_name/DATABRICKS_BUNDLE_ENGINE=direct ✅​p ✅​p ✅​p ✅​p 🔄​f ✅​p
❌​ TestAccept/bundle/resources/secret_scopes/basic ❌​F ✅​p ✅​p ✅​p ✅​p ✅​p
❌​ TestAccept/bundle/resources/secret_scopes/basic/DATABRICKS_BUNDLE_ENGINE=terraform ❌​F ✅​p ✅​p ✅​p ✅​p ✅​p
🔄​ TestAccept/bundle/resources/secret_scopes/delete_scope ✅​p ✅​p 🔄​f ✅​p ✅​p ✅​p
🔄​ TestAccept/bundle/resources/secret_scopes/delete_scope/DATABRICKS_BUNDLE_ENGINE=terraform ✅​p ✅​p 🔄​f ✅​p ✅​p ✅​p
💚​ TestAccept/bundle/resources/vector_search_endpoints/drift/recreated_same_name 💚​R 💚​R 💚​R 💚​R 💚​R 💚​R
🙈​ TestAccept/bundle/resources/vector_search_indexes/recreate/embedding_dimension 🙈​S 🙈​S 🙈​S 🙈​S 🙈​S 🙈​S
🙈​ TestAccept/ssh/connection 🙈​S 🙈​S 🙈​S 🙈​S 🙈​S 🙈​S
🔄​ TestSyncIncrementalFileOverwritesFolder ✅​p ✅​p ✅​p 🔄​f ✅​p ✅​p
🟨​ TestFetchRepositoryInfoAPI_FromRepo 🟨​K 🟨​K 🟨​K 💚​R 🙈​S 🙈​S
🟨​ TestFetchRepositoryInfoAPI_FromRepo/root 🟨​K 🟨​K 🟨​K 💚​R
🟨​ TestFetchRepositoryInfoAPI_FromRepo/subdir 🟨​K 🟨​K 🟨​K 💚​R
Top 50 slowest tests (at least 2 minutes):
duration env testname
13:09 gcp windows TestAccept/bundle/resources/apps/lifecycle-started/DATABRICKS_BUNDLE_ENGINE=direct
12:27 gcp linux TestAccept/bundle/resources/apps/lifecycle-started/DATABRICKS_BUNDLE_ENGINE=direct
11:22 azure windows TestAccept/bundle/resources/clusters/lifecycle-started/DATABRICKS_BUNDLE_ENGINE=direct
9:31 azure windows TestAccept/bundle/resources/apps/lifecycle-started/DATABRICKS_BUNDLE_ENGINE=direct
9:12 aws windows TestAccept/bundle/resources/clusters/lifecycle-started/DATABRICKS_BUNDLE_ENGINE=direct
9:02 gcp windows TestAccept/bundle/resources/clusters/lifecycle-started/DATABRICKS_BUNDLE_ENGINE=direct
8:41 aws linux TestAccept/bundle/resources/clusters/lifecycle-started-toggle/DATABRICKS_BUNDLE_ENGINE=direct
7:58 gcp linux TestAccept/bundle/invariant/destroy_idempotent/DATABRICKS_BUNDLE_ENGINE=direct/INPUT_CONFIG=cluster_apply_policy_default_values.yml.tmpl/READPLAN=
7:54 gcp linux TestAccept/bundle/resources/clusters/lifecycle-started/DATABRICKS_BUNDLE_ENGINE=direct
7:52 azure linux TestAccept/bundle/resources/apps/lifecycle-started/DATABRICKS_BUNDLE_ENGINE=direct
7:45 gcp linux TestAccept/bundle/invariant/destroy_idempotent/DATABRICKS_BUNDLE_ENGINE=direct/INPUT_CONFIG=cluster.yml.tmpl/READPLAN=
7:38 gcp linux TestAccept/bundle/resources/clusters/deploy/local_ssd_count/DATABRICKS_BUNDLE_ENGINE=direct
7:37 gcp linux TestAccept/bundle/config-remote-sync/multiple_resources/DATABRICKS_BUNDLE_ENGINE=direct
7:36 aws linux TestAccept/bundle/resources/apps/lifecycle-started/DATABRICKS_BUNDLE_ENGINE=direct
7:32 aws windows TestAccept/bundle/resources/apps/lifecycle-started/DATABRICKS_BUNDLE_ENGINE=direct
7:20 azure windows TestAccept/bundle/resources/clusters/resize-terminated-fallback/DATABRICKS_BUNDLE_ENGINE=direct
7:08 azure linux TestAccept/bundle/resources/clusters/lifecycle-started/DATABRICKS_BUNDLE_ENGINE=direct
7:01 aws linux TestAccept/bundle/resources/clusters/deploy/simple/DATABRICKS_BUNDLE_ENGINE=direct
6:48 gcp windows TestAccept/bundle/resources/clusters/deploy/local_ssd_count/DATABRICKS_BUNDLE_ENGINE=direct
6:45 aws linux TestAccept/bundle/resources/clusters/lifecycle-started/DATABRICKS_BUNDLE_ENGINE=direct
6:42 aws linux TestAccept/bundle/resources/clusters/deploy/update-after-create/DATABRICKS_BUNDLE_ENGINE=direct
6:41 aws windows TestAccept/bundle/deploy/spark-jar-task/DATABRICKS_BUNDLE_ENGINE=terraform
6:38 azure linux TestAccept/bundle/resources/clusters/lifecycle-started-toggle/DATABRICKS_BUNDLE_ENGINE=direct
6:02 aws windows TestAccept/bundle/resources/clusters/lifecycle-started-toggle/DATABRICKS_BUNDLE_ENGINE=direct
6:01 gcp windows TestAccept/bundle/resources/apps/lifecycle-started-omitted/DATABRICKS_BUNDLE_ENGINE=direct
6:00 aws linux TestAccept/bundle/deploy/spark-jar-task/DATABRICKS_BUNDLE_ENGINE=terraform
5:51 aws windows TestAccept/bundle/resources/postgres_endpoints/update_autoscaling/DATABRICKS_BUNDLE_ENGINE=terraform
5:46 gcp windows TestAccept/bundle/resources/apps/lifecycle-started-toggle/DATABRICKS_BUNDLE_ENGINE=direct
5:41 aws windows TestAccept/bundle/deploy/spark-jar-task/DATABRICKS_BUNDLE_ENGINE=direct
5:39 aws linux TestAccept/bundle/config-remote-sync/multiple_resources/DATABRICKS_BUNDLE_ENGINE=terraform
5:32 gcp windows TestAccept/bundle/invariant/delete_idempotent/DATABRICKS_BUNDLE_ENGINE=direct/INPUT_CONFIG=secret.yml.tmpl/READPLAN=1
5:31 gcp windows TestAccept/bundle/resources/clusters/lifecycle-started-toggle/DATABRICKS_BUNDLE_ENGINE=direct
5:30 gcp linux TestAccept/bundle/config-remote-sync/multiple_resources/DATABRICKS_BUNDLE_ENGINE=terraform
5:29 aws linux TestAccept/bundle/deploy/spark-jar-task/DATABRICKS_BUNDLE_ENGINE=direct
5:28 gcp windows TestAccept/bundle/deploy/spark-jar-task/DATABRICKS_BUNDLE_ENGINE=direct
5:11 gcp windows TestAccept/bundle/deploy/spark-jar-task/DATABRICKS_BUNDLE_ENGINE=terraform
5:03 aws linux TestAccept/bundle/resources/registered_models/basic/DATABRICKS_BUNDLE_ENGINE=terraform
4:59 gcp windows TestAccept/bundle/resources/apps/inline_config/DATABRICKS_BUNDLE_ENGINE=terraform
4:59 gcp linux TestAccept/bundle/resources/apps/lifecycle-started-omitted/DATABRICKS_BUNDLE_ENGINE=direct
4:56 aws linux TestAccept/bundle/resources/clusters/deploy/data_security_mode/DATABRICKS_BUNDLE_ENGINE=direct
4:56 gcp linux TestAccept/bundle/resources/apps/lifecycle-started-toggle/DATABRICKS_BUNDLE_ENGINE=direct
4:51 gcp linux TestAccept/bundle/resources/clusters/lifecycle-started-toggle/DATABRICKS_BUNDLE_ENGINE=direct
4:49 aws windows TestAccept/bundle/invariant/delete_idempotent/DATABRICKS_BUNDLE_ENGINE=direct/INPUT_CONFIG=job_pydabs_1000_tasks.yml.tmpl/READPLAN=
4:44 azure linux TestAccept/bundle/invariant/delete_idempotent/DATABRICKS_BUNDLE_ENGINE=direct/INPUT_CONFIG=app.yml.tmpl/READPLAN=1
4:41 gcp windows TestAccept/bundle/invariant/delete_idempotent/DATABRICKS_BUNDLE_ENGINE=direct/INPUT_CONFIG=schema_uppercase_name.yml.tmpl/READPLAN=1
4:39 azure windows TestAccept/bundle/resources/apps/lifecycle-started-toggle/DATABRICKS_BUNDLE_ENGINE=direct
4:37 gcp linux TestAccept/bundle/templates/default-python/combinations/classic/DATABRICKS_BUNDLE_ENGINE=terraform/DLT=no/NBOOK=no/PY=yes/READPLAN=
4:37 aws windows TestAccept/bundle/invariant/delete_idempotent/DATABRICKS_BUNDLE_ENGINE=direct/INPUT_CONFIG=cluster.yml.tmpl/READPLAN=1
4:37 azure linux TestAccept/bundle/config-remote-sync/multiple_resources/DATABRICKS_BUNDLE_ENGINE=direct
4:36 gcp windows TestAccept/bundle/resources/grants/schemas/all_privileges_coexist/DATABRICKS_BUNDLE_ENGINE=direct

Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment

Labels

None yet

Projects

None yet

Development

Successfully merging this pull request may close these issues.

3 participants